home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 3 / Info_Mac_1994-01.iso / Development / 4D Externals / ReadWriteVar / ReadWriteVar READ ME! next >
Encoding:
Text File  |  1993-07-25  |  13.6 KB  |  277 lines  |  [TEXT/ttxt]

  1. ReadWriteVar Package for 4th Dimension, version 1.0.1
  2.  
  3. This package is © 1993 Scott Ribe, all rights reserved.
  4.  
  5. Use of this package requires a $25 shareware fee. This fee entitles one developer to use this package in an unlimited number of applications and to distribute those applications without limit.
  6.  
  7. However, you may distribute it only as part of a complete 4D application. You may not resell it by itself, or as part of any kind of shell or toolkit without the author's express written permission. You may not remove or alter any portion of this notice or the comments.
  8.  
  9. The only difference between 1.0 and 1.0.1 is that when writing large text or pict arrays 1.0.1 will give a little bit of time (and I mean LITTLE) to other processes instead of completely hogging the CPU.
  10.  
  11. Please note, these are low-level routines that go right to the disk. You must be very careful using them. For instance, if you try to close an already closed file, that could result in your wiping out your entire disk. Keep backups, be careful, use the externals properly.
  12.  
  13. Scott Ribe
  14.  
  15. CIS 73507,3041
  16.  
  17. 604 Inverness Cliffs
  18. Birmingham, AL 35242
  19.  
  20. INSTALLATION:
  21. ==============
  22.  
  23. You may use 4D External Mover to install this package. However, I have included the resources necessary to make the commands group into three popups in the procedure editor, and these will not be copied by 4D External Mover, or 4D External Mover Plus 1.0 (I've not tested 1.0.1). If you want the popups, first install with 4D External Mover, then open the external file and your Proc.ext or structure with ResEdit, find the 4DPX name "ReadWriteVar", note its number, copy and paste the THM# and FON# resources from the external file, and make sure they have the same number as the 4DPX.
  24.  
  25. PURPOSE:
  26. ==========
  27.  
  28. This package is designed primarily to allow you to read and write arrays to disk. 
  29.  
  30. In 4D if you use SEND VARIABLE    on an array, all that gets written is the integer representing the currently selected item of the array. In order to write the entire array, you have to code a loop that writes out each element individually.
  31.  
  32. Depending on the kind of array being manipulate, this package seems to be 10-100 times faster than the equivalent compiled code. The data elements of arrays of fixed-length values are written out as a single block. For variable-length data (text and pictures) short elements are buffered up and written out in blocks.
  33.  
  34. I would liked to have just written a pair of externals to read and write arrays. But unfortunately, I don't know how to get at the file opened by SET CHANNEL, and the value returned by Open document is not, as one might expect, a normal Mac file reference number. So I had to provide commands to read and write all the other data types as well.
  35.  
  36. LIMITS:
  37. =======
  38.  
  39. The file manipulation abilities of this package are limited to creating, opening, and closing files. There are packages available that provide extensive file-system functionality, and I do not intend to replicate them or compete with them.
  40.  
  41. If you want to get directory lists, or examine the finder information on a file, or move, copy, rename, or delete files, you can download Bob Pulgino's excellent, free, package FilePack.
  42.  
  43. If you want to find the paths to System 7 folders (preferences, especially comes to mind as a useful one with this package), you can buy either Foresight's Toolset (CIS 71131,3557) or Bob's PowerPacks (CIS 71332,2147).
  44.  
  45. If you want a fuller set of file primitives, such as GetFilePos, SetFilePos, GetFIleEOF, SetFileEOF, you can get PowerPacks.
  46.  
  47. QUICK START:
  48. ==============
  49.  
  50. Basically you open the file:
  51.  
  52. CreateVarFile("stuff";"4D03";"TEXT")
  53. $doc:=OpenVarFile("stuff")
  54.  
  55. Write your data:
  56.  
  57. WriteVarLong($doc;myVersNum)
  58. WriteVarArray($doc;anArray)
  59.  
  60. Close the file:
  61.  
  62. CloseVarFile($doc)
  63.  
  64. Reopen the file and read back the data:
  65.  
  66. $doc:=OpenVarFile("stuff")
  67. If (ReadWriteVarErr = 0)
  68.   $num:=ReadVarLong($doc)
  69.   If ($num=myVersNum)
  70.     ReadVarArray($doc;anArray)
  71.   else
  72.     Alert ("The file was created with an incompatible version of this application!")
  73.   end if
  74. else
  75.   Alert ("Error ("+String(ReadWriteVarErr)+") opening the file!")
  76. end if
  77.  
  78. Of course, you should be more careful about error checking than in this example. (You should certainly check for errors when creating and writing the file!) And it's always a good idea to make the first item written into the file information describing the file format, so that you can take appropriate action if you change the format in some future version.
  79.  
  80. Note that each time you write a value, the package writes a tag describing the value's type. When you read data these tags are checked to make sure you read the same types that you wrote out. A type mismatch error code is 59.
  81.  
  82. PASSING ARGUMENTS:
  83. ===================
  84.  
  85. The values being copied into a file, that is the values being passed as the second argument to WriteVarXXX, can be anything: globals, locals, interprocess, constants, fields, or array elements. Values that will be modified must be passed as global variables; that is the arrays in ReadVarArray calls.
  86.  
  87. 4D generally only allows externals to modify the value of global variables. So any value that is going to be modified should be a global variable. In 3.0, this includes interprocess and process variables.
  88.  
  89. In 4D 3.0 ReadVarArrayArray($doc;$LocalArray) seems to work, but I wouldn't trust it without exhaustive testing. 
  90.  
  91. Finally, if you keep the file reference number in a global variable then you can close the file if your procedure aborts.
  92.  
  93. REFERENCE:
  94. ===========
  95.  
  96. ReadWriteVarErr -> L
  97. --------------------
  98.  
  99. Returns any error posted by the last call into this package. Mostly Mac file manager errors. No error is 0. Read past the end of the file is EOF (-39). A type mismatch error is 59.
  100.  
  101. Under 3.0 returns only the error posted by the last call into this package from the same process.
  102.  
  103. CreateVarFile(S;S;S)
  104. -------------------
  105.  
  106. Creates a file using the pathname specified in the first parameter. The pathname may be either fully qualified, or relative to the current default directory. The second and third parameters are the creator code and type code, respectively. This does NOT open the file for access. If the file already exists, this does nothing except post an error code -48.
  107.  
  108. OpenVarFile(S) -> L
  109. ------------------
  110.  
  111. Opens the file indicated by the pathname and returns a file reference number. The file named must already exist, therefore you should call CreateVarFile before calling OpenVarFile.
  112.  
  113. WriteVarShort(long;short)
  114. ------------------------
  115.  
  116. Writes the short integer value into the file at the current read/write position.
  117.  
  118. ReadVarShort(long) -> short
  119. --------------------------
  120.  
  121. Returns the short integer value from  the file's current read/write position.
  122.  
  123. WriteVarLong(long;long)
  124. ----------------------
  125.  
  126. Writes the long integer value into the file at the current read/write position.
  127.  
  128. ReadVarLong(long) -> long
  129. ------------------------
  130.  
  131. Returns the long integer value from  the file's current read/write position.
  132.  
  133. WriteVarReal(long;real)
  134. ----------------------
  135.  
  136. Writes the real value into the file at the current read/write position.
  137.  
  138. ReadVarReal(long) -> real
  139. -----------------------
  140.  
  141. Returns the real value from  the file's current read/write position.
  142.  
  143. WriteVarDate(long;date)
  144. ----------------------
  145.  
  146. Writes the date value into the file at the current read/write position.
  147.  
  148. ReadVarDate(long) -> date
  149. ------------------------
  150.  
  151. Returns the date value from  the file's current read/write position.
  152.  
  153. WriteVarString(long;string)
  154. -------------------------
  155.  
  156. Writes the string value into the file at the current read/write position.
  157.  
  158. ReadVarString(long) -> string
  159. ---------------------------
  160.  
  161. Returns the string value from  the file's current read/write position.
  162.  
  163. WriteVarText(long;text)
  164. ----------------------
  165.  
  166. Writes the text value into the file at the current read/write position.
  167.  
  168. ReadVarText(long) -> text
  169. ------------------------
  170.  
  171. Returns the text value from  the file's current read/write position.
  172.  
  173. WriteVarPict(long;picture)
  174. -------------------------
  175.  
  176. Writes the pict value into the file at the current read/write position.
  177.  
  178. ReadVarPict(long) -> picture
  179. --------------------------
  180.  
  181. Returns the pict value from  the file's current read/write position.
  182.  
  183. WriteVarArray(long;array)
  184. ------------------------
  185.  
  186. Writes the array (and the index of its currently selected element) into the file at the current read/write position.
  187.  
  188. This works for all array types, 1 or 2 dimension, any size up to the limit of available disk space.
  189.  
  190. Note also that 4D's conventions regarding 2D arrays is followed strictly. A column of a 2D array is itself precisely an array of the base type. So:
  191.  
  192. ARRAY TEXT(myArray;5;10)
  193. WriteVarArray(myFile;myArray{5})
  194.  
  195. is perfectly legal.
  196.  
  197. Both the type and ordinality of the array are considered part of the value's type for error checking when reading the array back. For string arrays the string size is considered part of the type as well, but a size mismatch does not generate an error.
  198.  
  199. ReadVarArray(long;array)
  200. ----------------
  201.  
  202. Reads the array (and the index of its currently selected element) from  the file's current read/write position.
  203.  
  204. This works for all array types, 1 or 2 dimension, any size up to the limit of available memory. The procedure will redimension the array as needed.
  205.  
  206. Note also that 4D's conventions regarding 2D arrays is followed strictly. A column of a 2D array is itself precisely an array of the base type. So:
  207.  
  208. ARRAY TEXT(myArray;5;10)
  209. ReadVarArray(myFile;myArray{5})
  210.  
  211. is perfectly legal.
  212.  
  213. Both the type and ordinality of the array are considered part of the value's type for error checking when reading the array back.
  214.  
  215. If you write from a string array and then read back into a string array whose elements are of a different size, no error will be posted. Instead the strings in the file will be properly read into the new array: truncated (for a shorter destination) or left-aligned (for a longer destination). The read operation will be much faster if the original source and destination arrays have elements of the same size, because I can just use a single BlockMove instead of handling each string separately.
  216.  
  217. If there is not enough memory available to build the new array, the existing array will be destroyed before that is discovered. The procedure will in that case create a 0-dimensioned array with 1 null element and return it, so that 4D will not crash on a subsequent access to the array. (Of course the error will be available via ReadWriteVarErr as always.)
  218.  
  219. ===================================================================
  220. FOR EXPERTS ONLY!!!
  221. ===================================================================
  222.  
  223. To all you out there who know what you're doing, please don't take offense at the tone of the comments for the following three commands. This stuff really is for knowledgeable C programmers and I just wanted to very strongly discourage folks from getting in over their heads...
  224.  
  225. WriteVarHandle(long;long)
  226. -------------------------
  227.  
  228. Assumes that the long integer passed as the second parameter is actually a handle created by some other external package, takes the data in that handle and copies it into the file, typed as a PICT.
  229.  
  230. The sequence:
  231.  
  232. WriteVarHandle(myFile;myHdl1)
  233.  
  234. close & reopen the file
  235.  
  236. myHdl2:=ReadVarHandle(myFile)
  237.  
  238. cause myHdl2 to be a handle to a copy of the data in myHdl1.
  239.  
  240. You can follow WriteVarHandle with ReadVarPict, or WriteVarPict with ReadVarHandle, and no error will be generated, the position will be advanced, everything will be OK, and you can keep reading. I just can't think of a reason WHY you'd want to do that, and don't know what the heck you'd do with the resulting data??
  241.  
  242. You should know EXACTLY what you are doing and what the structure of the data in your handle is before calling this procedure. Note in particular that if the handle contains other handles or pointers, then of course only the handles or pointers, not the data they reference, will be copied. Therefore if you use this to copy a handle that is subsequently disposed by its creator, your copy will contain invalid references, and using it will probably crash your system. (Yep, it can be really ugly when one half of a pair of Siamese twin handles dies...)
  243.  
  244. And of course you should be sure that the data in the handle will be valid by the next time you open and read from the file.
  245.  
  246. DON'T ASK ME FOR HELP WITH THE THREE HANDLE-ORIENTED COMMANDS. I AM NOT A SUBSTITUTE FOR INSIDE MACINTOSH.
  247.  
  248. ReadVarHandle(long) -> long
  249. --------------------------
  250.  
  251. Requires that the next item to be read from the file is of type PICT, allocates a handle for the data, copies the data into it, and returns the handle as a long integer.
  252.  
  253. The pict data could have been put into the file using either WriteVarPict or WriteVarHandle. (But only WriteVarHandle really makes sense.)
  254.  
  255. If a4dLong contains a handle then:
  256.  
  257. a4dLong := ReadVarHandle(myFile)
  258.  
  259. Does NOT dispose the handle currently in a4dLong, you just lose track of it. Once again, you should know what you're doing before you start messing around with handles.
  260.  
  261. DisposBdlHandle(long)
  262. ---------------
  263.  
  264. If you have to ask what this does, you should not ever consider calling it under any circumstances!
  265.  
  266. Source code is (roughly, after factoring out my macros for accessing and casting 4D package arguments):
  267.  
  268. DisposHandle (*(Handle *)(PackArgs[1]));
  269.  
  270. If you don't understand that, go back  and reread the preceding warnings about messing with the handle commands.
  271.  
  272. TECHIE STUFF:
  273. =============
  274.  
  275. The value returned by OpenVarFile really is just a file reference number (or access path number) as returned by FSOpen. Therefore if you wish to write your own externals to manipulate these files (or use PowerPacks routines to create, open, or manipulate them) you may easily do so.
  276.  
  277. Just be sure to read/write your own data types in precisely matched pairs. Don't try to read data that I write, and don't try to write data for me to read.